package com.eregg.learn.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class NIOServer {

    public static void main(String[] args)throws IOException {
        //将服务器端的Channel注册到该Selector中。
        Selector serverSelector = Selector.open();
        //当新的客户端发送数据时，将客户端channel注册到该Selector。
        Selector clientSelector = Selector.open();

        new Thread(() ->{
            try {
                ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
                serverSocketChannel.socket().bind(new InetSocketAddress(8000));
                serverSocketChannel.configureBlocking(false);
                serverSocketChannel.register(serverSelector, SelectionKey.OP_ACCEPT);

                while (true){
                    if(serverSelector.select(1) > 0){
                        Set<SelectionKey> selectionKeys = serverSelector.selectedKeys();
                        Iterator<SelectionKey> iterator = selectionKeys.iterator();
                        while (iterator.hasNext()){
                            SelectionKey key = iterator.next();
                            if(key.isAcceptable()){
                                try {
                                    SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
                                    socketChannel.configureBlocking(false);
                                    socketChannel.register(clientSelector, SelectionKey.OP_READ);
                                    SocketAddress remoteSocketAddress = socketChannel.socket().getRemoteSocketAddress();
                                    int port = socketChannel.socket().getPort();
                                    System.out.println(String.format("新的客户端连接进来：IP:%s,port:%s", remoteSocketAddress.toString(), port));
                                } finally {
                                    iterator.remove();
                                }

                            }
                        }
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() ->{
            while (true){
                try {
                    if (clientSelector.select(1) > 0){
                        Set<SelectionKey> selectionKeys = clientSelector.selectedKeys();
                        Iterator<SelectionKey> iterator = selectionKeys.iterator();
                        while (iterator.hasNext()){
                            SelectionKey key = iterator.next();
                            try {
                                if(key.isReadable()){
                                    SocketChannel socketChannel = (SocketChannel) key.channel();
                                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                                    socketChannel.read(buffer);
                                    buffer.flip();
                                    System.out.println(Charset.defaultCharset().decode(buffer).toString());
                                }
                            } finally {
                                iterator.remove();
                            }

                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        System.out.println("server startup port:8000");
    }
}
